热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

时会|这个地方_S5PV210开发板用汇编设置栈和调用C语言

篇首语:本文由编程笔记#小编为大家整理,主要介绍了S5PV210开发板用汇编设置栈和调用C语言相关的知识,希望对你有一定的参考价值。使用C语言前为什么要先用汇编设置栈&#

篇首语:本文由编程笔记#小编为大家整理,主要介绍了S5PV210开发板用汇编设置栈和调用C语言相关的知识,希望对你有一定的参考价值。


使用C语言前为什么要先用汇编设置栈?
C语言程序运行时需要栈,因为C语言中的局部变量都是用栈来实现的,如果没有设置栈就使用C语言,局部变量就会落空,程序就会死掉,所以在使用C语言前,我们需要先在汇编编写的启动代码中设置栈。

为什么使用51单片机和Ubuntu编写应用程序时我们没有设置栈依然能使用C语言?
原因是在单片机中已经由硬件设置提供了一个默认可用的栈,而在应用程序中我们编写的C程序其实并不是全部,编译器(gcc)在链接时会帮我们自动添加一个头,这个头就是一段引导C程序能够执行的汇编代码,在这个代码中就帮我们的C程序设置了栈及其他的运行时需要。

为什么不同CPU模式下都有各自独立的sp寄存器?
如果各个模式都使用同一个sp,意味着整个程序(操作系统内核程序,用户应用程序)都使用同一个栈,这样做,一旦用户程序编写出错(栈溢出),将会影响操作系统的正常运行,操作系统会崩溃,同时运行在操作系统上的其他应用程序也会崩溃。所以各个模式下要使用不同的sp,使用不同的栈,操作系统有自己的栈,每个应用程序也有自己的栈,互不干扰。

怎么设置栈?
我们要设置栈,并不是设置所有CPU模式下的栈,而是设置当前CPU模式下的栈,因为这个程序可能只用到一种CPU模式。S5PV210复位后默认是进入SVN模式下的,我们设置当前模式下的栈,只需直接操作sp即可。
需要注意的是,栈必须是当前一段可用的内存(可用的意思是这个地方是有被初始化过的可以访问的内存,而且这个内存只会被我们用作栈,不会被其他程序征用)
当前CPU刚复位(刚启动),外部的DDR尚未初始化,需要我们后续对其初始化,所以目前可用的内存只有内部的SRAM(因为它不需初始化即可使用)。因此我们只能在SRAM中找一段内存来作为SVC的栈。

在ARM中,ATPCS(ARM关于程序应该怎么实现的一个规范)要求使用满减栈,结合iROM_application_note中的memory map,可知SVC栈应该设置为0xD0037D80。
示例代码:
start.S

#define WTCON 0xE2700000
#define SVN_STACK 0xD0037D80
.global _start
_start:
/*关看门狗*/
ldr r0, =0
ldr r1, =WTCON
str r0, [r1]
/*设置SVN栈*/
ldr sp, =SVN_STACK
/*开/关icache*/
mrc p15,0,r0,c1,c0,0; // 读出cp15的c1到r0中
//bic r0, r0, #(1<<12) // bit12 置0 关icache
orr r0, r0, #(1<<12) // bit12 置1 开icache
mcr p15,0,r0,c1,c0,0; // 把r0写到cp15的c1中
/*流水灯*/
bl led_blink

b .

led.c

#define GPJ0CON 0xE0200240
#define GPJ0DAT 0xE0200244
#define rGPJ0CON *((volatile unsigned int*)GPJ0CON)
#define rGPJ0DAT *((volatile unsigned int*)GPJ0DAT)
void delay(void);
void led_blink(void)

rGPJ0CON &#61; 0x11111111;
while(1)

rGPJ0DAT &#61; ~(1<<3);
delay();
rGPJ0DAT &#61; ~(1<<4);
delay();
rGPJ0DAT &#61; ~(1<<5);
delay();


void delay(void)

volatile unsigned int i &#61; 3000000;
while(i--);

/* volatile的作用是防止编译器优化我们的变量&#xff0c;有时候编译器会认为我们对这个变量的操作是无意义的&#xff0c;例如对一个数&#43;1然后-1&#xff0c;有些编译器会直接保持原值不变
&#xff0c;这样做的结果可能导致我们的程序不对&#xff0c;所以为了不受编译器的这个影响&#xff0c;加上
volatile会使程序更加稳定&#xff0c;一般对易变的变量都加上volatile&#xff0c;至于加不加volatile结果会不会有什么不同&#xff0c;取决于编译器&#xff0c;一些编译器不会对此优化&#xff0c;一些则会。 */

Makefile

led.bin: start.o led.o
arm-linux-ld -Ttext 0x0 -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 led.bin 210.bin

%.o : %.S
arm-linux-gcc -o $&#64; $< -c -nostdlib
%.o : %.c
arm-linux-gcc -o $&#64; $< -c -nostdlib
#这里要加-nostdlib&#xff0c;作用是不使用编译器自带的标准函数库文件
#因为led.c文件中的delay函数与编译器自带的标准函数库中的delay重名
#默认会去使用编译器自带的&#xff0c;我们要使用自己定义的话就会报错
#相当于你一个C程序定义了两个同名函数
clean:
rm *.o *.elf *.bin *.dis mkx210 -f

推荐阅读
  • PHP中元素的计量单位是什么? ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • MySQL性能优化与调参指南【数据库管理】
    本文详细探讨了MySQL数据库的性能优化与参数调整技巧,旨在帮助数据库管理员和开发人员提升系统的运行效率。内容涵盖索引优化、查询优化、配置参数调整等方面,结合实际案例进行深入分析,提供实用的操作建议。此外,还介绍了常见的性能监控工具和方法,助力读者全面掌握MySQL性能优化的核心技能。 ... [详细]
  • JVM参数设置与命令行工具详解
    JVM参数配置与命令行工具的深入解析旨在优化系统性能,通过合理设置JVM参数,确保在高吞吐量的前提下,有效减少垃圾回收(GC)的频率,进而降低系统停顿时间,提升服务的稳定性和响应速度。此外,本文还将详细介绍常用的JVM命令行工具,帮助开发者更好地监控和调优JVM运行状态。 ... [详细]
  • 探讨 jBPM 数据库表结构设计的精要与实践
    探讨 jBPM 数据库表结构设计的精要与实践 ... [详细]
  • 掌握DSP必备的56个核心问题,我已经将其收藏以备不时之需! ... [详细]
  • Node.js 教程第五讲:深入解析 EventEmitter(事件监听与发射机制)
    本文将深入探讨 Node.js 中的 EventEmitter 模块,详细介绍其在事件监听与发射机制中的应用。内容涵盖事件驱动的基本概念、如何在 Node.js 中注册和触发自定义事件,以及 EventEmitter 的核心 API 和使用方法。通过本教程,读者将能够全面理解并熟练运用 EventEmitter 进行高效的事件处理。 ... [详细]
  • 如何使用 net.sf.extjwnl.data.Word 类及其代码示例详解 ... [详细]
  • 在《PHP应用性能优化实战指南:从理论到实践的全面解析》一文中,作者分享了一次实际的PHP应用优化经验。文章回顾了先前进行的一次优化项目,指出即使系统运行时间较长后出现的各种问题和性能瓶颈,通过采用一些通用的优化策略仍然能够有效解决。文中不仅详细阐述了优化的具体步骤和方法,还结合实例分析了优化前后的性能对比,为读者提供了宝贵的参考和借鉴。 ... [详细]
  • 掌握PHP框架开发与应用的核心知识点:构建高效PHP框架所需的技术与能力综述
    掌握PHP框架开发与应用的核心知识点对于构建高效PHP框架至关重要。本文综述了开发PHP框架所需的关键技术和能力,包括但不限于对PHP语言的深入理解、设计模式的应用、数据库操作、安全性措施以及性能优化等方面。对于初学者而言,熟悉主流框架如Laravel、Symfony等的实际应用场景,有助于更好地理解和掌握自定义框架开发的精髓。 ... [详细]
  • 全面解析Java虚拟机:内存模型深度剖析 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
  • DHCP三层交换机设置方式全局模式和接口模式设置方式和命令resetsave回车输入yreboot输入n输入y重启后就恢复默认设置了默认用户名密码adminAdmin@huawei ... [详细]
  • 本文探讨了将PEBuilder转换为DIBooter.sh的方法,重点介绍了如何将DI工具集成到启动层,实现离线镜像引导安装。通过使用DD命令替代传统的grub-install工具,实现了GRUB的离线安装。此外,还详细解析了bootice工具的工作原理及其在该过程中的应用,确保系统在无网络环境下也能顺利引导和安装。 ... [详细]
  • 深入RTOS实践,面对原子操作提问竟感困惑
    在实时操作系统(RTOS)的实践中,尽管已经积累了丰富的经验,但在面对原子操作的具体问题时,仍感到困惑。本文将深入探讨RTOS中的原子操作机制,分析其在多任务环境下的重要性和实现方式,并结合实际案例解析常见的问题及解决方案,帮助读者更好地理解和应用这一关键技术。 ... [详细]
author-avatar
竹茹士弘宜来
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有